package com.code2roc.fastboot.framework.config;

import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.code2roc.fastboot.framework.auth.TokenAuthInterceptor;
import com.code2roc.fastboot.framework.extra.errorhandle.ResponseStatusInterceptor;
import com.code2roc.fastboot.framework.extra.formupdate.BaseModelMethodArgumentResolver;
import com.code2roc.fastboot.framework.extra.jsonhandle.FastJsonPropertyNameFilter;
import com.code2roc.fastboot.framework.extra.jsonhandle.FastJsonPropertyValueFilter;
import com.code2roc.fastboot.framework.extra.requesthandle.HttpServletRequestReplacedFilter;
import com.code2roc.fastboot.framework.file.IFileOperate;
import com.code2roc.fastboot.framework.file.LocalFileOperate;
import com.code2roc.fastboot.framework.file.LocalFileStoargeProperty;
import com.code2roc.fastboot.framework.security.CORSFilter;
import com.code2roc.fastboot.framework.security.SQLInjectInterceptor;
import com.code2roc.fastboot.framework.security.XSSFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;

public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private SystemConfig systemConfig;
    @Autowired
    private TokenAuthInterceptor tokenAuthIntecept;
    @Autowired
    private ResponseStatusInterceptor responseStatusInterceptor;
    @Autowired
    private SQLInjectInterceptor sqlInjectInterceptor;
    @Autowired
    private Environment env;

    //拦截器注册
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenAuthIntecept).addPathPatterns("/**").excludePathPatterns("/" + systemConfig.getSystemTag() + "/**");
        registry.addInterceptor(sqlInjectInterceptor).addPathPatterns("/**");
        registry.addInterceptor(responseStatusInterceptor).addPathPatterns("/**");
    }

    //json序列化规则
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //1.需要定义一个convert转换消息的对象;
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        //2.添加fastJson的配置信息，比如：是否要格式化返回的json数据;
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        //全局指定了日期格式
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        //指定json返回规则（框架个性化控制）
        fastJsonConfig.setSerializeFilters(new SerializeFilter[]{new FastJsonPropertyNameFilter(),new FastJsonPropertyValueFilter()});
        //3处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        //4.在convert中添加配置信息.
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        //5.将convert添加到converters当中.
        converters.add(fastJsonHttpMessageConverter);
    }

    //表单提交参数解析规则
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new BaseModelMethodArgumentResolver());
    }

    //注册参数过滤器
    @Bean
    public FilterRegistrationBean httpServletRequestReplacedRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new HttpServletRequestReplacedFilter());
        registration.addUrlPatterns("/*");
        registration.addInitParameter("paramName", "paramValue");
        registration.setName("httpServletRequestReplacedFilter");
        return registration;
    }

    //注册跨域过滤器
    @Bean
    public FilterRegistrationBean cORSFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new CORSFilter());
        registration.addUrlPatterns("/*");
        registration.addInitParameter("paramName", "paramValue");
        registration.setName("cORSFilter");
        return registration;
    }

    //xss防御过滤器
    @Bean
    @ConditionalOnProperty(name = "security.openXSS", havingValue = "true", matchIfMissing = true)
    public FilterRegistrationBean xSSFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new XSSFilter());
        registration.addUrlPatterns("/*");
        registration.addInitParameter("paramName", "paramValue");
        registration.setName("xssFilter");
        return registration;
    }

    //静态文件直接访问路径
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //第一个方法设置访问路径前缀，第二个方法设置资源路径
        registry.addResourceHandler("/"+systemConfig.getSystemTag()+"/**").addResourceLocations(systemConfig.getStaticLocations().split(","));
    }


    //本地文件实现
    @Bean(name="local")
    public IFileOperate localFileOperate() {
        String storePath = env.getProperty("file.local.storePath");
        LocalFileStoargeProperty localFileStoargeProperty = new LocalFileStoargeProperty(storePath);
        return new LocalFileOperate(localFileStoargeProperty);
    }
}
